home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 April: Mac OS SDK / Dev.CD Apr 99 SDK1.toast / Development Kits / Interfaces&Libraries / Universal / Interfaces / RIncludes / MixedMode.r < prev    next >
Encoding:
Text File  |  1998-08-17  |  13.6 KB  |  432 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        MixedMode.r
  3.  
  4.      Contains:    Mixed Mode Manager Interfaces.
  5.  
  6.      Version:    Technology:    Mac OS 8
  7.                  Release:    Universal Interfaces 3.2
  8.  
  9.      Copyright:    © 1992-1998 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        For bug reports, consult the following page on
  12.                  the World Wide Web:
  13.  
  14.                      http://developer.apple.com/bugreporter/
  15.  
  16. */
  17.  
  18. #ifndef __MIXEDMODE_R__
  19. #define __MIXEDMODE_R__
  20.  
  21. #ifndef __CONDITIONALMACROS_R__
  22. #include "ConditionalMacros.r"
  23. #endif
  24.  
  25. #define kRoutineDescriptorVersion         7
  26. #define _MixedModeMagic                 0xAAFE
  27. #define kCurrentMixedModeStateRecord     1
  28. #define kPascalStackBased                 0
  29. #define kCStackBased                     1
  30. #define kRegisterBased                     2
  31. #define kD0DispatchedPascalStackBased     8
  32. #define kD1DispatchedPascalStackBased     12
  33. #define kD0DispatchedCStackBased         9
  34. #define kStackDispatchedPascalStackBased  14
  35. #define kThinkCStackBased                 5
  36.  
  37. #define kM68kISA                         0
  38. #define kPowerPCISA                     1
  39.  
  40. #define kOld68kRTA                         0x00
  41. #define kPowerPCRTA                     0x00
  42. #define kCFM68kRTA                         0x10
  43.  
  44. #define kRegisterD0                     0
  45. #define kRegisterD1                     1
  46. #define kRegisterD2                     2
  47. #define kRegisterD3                     3
  48. #define kRegisterD4                     8
  49. #define kRegisterD5                     9
  50. #define kRegisterD6                     10
  51. #define kRegisterD7                     11
  52. #define kRegisterA0                     4
  53. #define kRegisterA1                     5
  54. #define kRegisterA2                     6
  55. #define kRegisterA3                     7
  56. #define kRegisterA4                     12
  57. #define kRegisterA5                     13
  58. #define kRegisterA6                     14                    /*  A7 is the same as the PowerPC SP  */
  59. #define kCCRegisterCBit                 16
  60. #define kCCRegisterVBit                 17
  61. #define kCCRegisterZBit                 18
  62. #define kCCRegisterNBit                 19
  63. #define kCCRegisterXBit                 20
  64.  
  65. #define kNoByteCode                     0
  66. #define kOneByteCode                     1
  67. #define kTwoByteCode                     2
  68. #define kFourByteCode                     3
  69.  
  70. #define kProcDescriptorIsAbsolute         0x00
  71. #define kProcDescriptorIsRelative         0x01
  72.  
  73. #define kFragmentIsPrepared             0x00
  74. #define kFragmentNeedsPreparing         0x02
  75.  
  76. #define kUseCurrentISA                     0x00
  77. #define kUseNativeISA                     0x04
  78.  
  79. #define kPassSelector                     0x00
  80. #define kDontPassSelector                 0x08
  81.  
  82. #define kRoutineIsNotDispatchedDefaultRoutine  0x00
  83. #define kRoutineIsDispatchedDefaultRoutine  0x10
  84.  
  85. #define kProcDescriptorIsProcPtr         0x00
  86. #define kProcDescriptorIsIndex             0x20
  87.  
  88. #define kSelectorsAreNotIndexable         0x00
  89. #define kSelectorsAreIndexable             0x01
  90.  
  91.                                                             /*  Calling Convention Offsets  */
  92. #define kCallingConventionWidth         4
  93. #define kCallingConventionPhase         0
  94. #define kCallingConventionMask             0x0F                /*  Result Offsets  */
  95. #define kResultSizeWidth                 2
  96. #define kResultSizePhase                 4
  97. #define kResultSizeMask                 0x30                /*  Parameter offsets & widths  */
  98. #define kStackParameterWidth             2
  99. #define kStackParameterPhase             6
  100. #define kStackParameterMask             0xFFFFFFC0            /*  Register Result Location offsets & widths  */
  101. #define kRegisterResultLocationWidth     5
  102. #define kRegisterResultLocationPhase     6                    /*  Register Parameter offsets & widths  */
  103. #define kRegisterParameterWidth         5
  104. #define kRegisterParameterPhase         11
  105. #define kRegisterParameterMask             0x7FFFF800
  106. #define kRegisterParameterSizePhase     0
  107. #define kRegisterParameterSizeWidth     2
  108. #define kRegisterParameterWhichPhase     2
  109. #define kRegisterParameterWhichWidth     3                    /*  Dispatched Stack Routine Selector offsets & widths  */
  110. #define kDispatchedSelectorSizeWidth     2
  111. #define kDispatchedSelectorSizePhase     6                    /*  Dispatched Stack Routine Parameter offsets  */
  112. #define kDispatchedParameterPhase         8                    /*  Special Case offsets & widths  */
  113. #define kSpecialCaseSelectorWidth         6
  114. #define kSpecialCaseSelectorPhase         4
  115. #define kSpecialCaseSelectorMask         0x03F0
  116.  
  117. #define kSpecialCase                     0x000F                /*  (CallingConventionType)  */
  118.                                                             /*  all of the special cases enumerated.  The selector field is 6 bits wide  */
  119. #define kSpecialCaseHighHook             0
  120. #define kSpecialCaseCaretHook             0                    /*  same as kSpecialCaseHighHook  */
  121. #define kSpecialCaseEOLHook             1
  122. #define kSpecialCaseWidthHook             2
  123. #define kSpecialCaseTextWidthHook         2                    /*  same as kSpecialCaseWidthHook  */
  124. #define kSpecialCaseNWidthHook             3
  125. #define kSpecialCaseDrawHook             4
  126. #define kSpecialCaseHitTestHook         5
  127. #define kSpecialCaseTEFindWord             6
  128. #define kSpecialCaseProtocolHandler     7
  129. #define kSpecialCaseSocketListener         8
  130. #define kSpecialCaseTERecalc             9
  131. #define kSpecialCaseTEDoText             10
  132. #define kSpecialCaseGNEFilterProc         11
  133. #define kSpecialCaseMBarHook             12
  134.  
  135. #define    GoMixedModeTrapType    unsigned hex integer
  136. #define    VersionType byte
  137. #define    SelectorsAreIndexableType boolean
  138. #define    Reserved1Type fill long
  139. #define    Reserved2Type fill byte
  140. #define    SelectorInfoType hex byte
  141. #define    RoutineCountType integer
  142. #define    ProcInfoType binary longint
  143. #define    Reserved3Type fill byte
  144. #define    ISAType byte
  145. #define    ProcDescriptorIsRelativeType boolean
  146. #define    FragmentNeedsPreparingType boolean
  147. #define    UseNativeISAType boolean
  148. #define    DontPassSelectorType boolean
  149. #define    RoutineIsDispatchedDefaultType boolean
  150. #define    ProcDescriptorType longint
  151. #define    Reserved4Type fill long
  152. #define    SelectorType longint
  153. /*
  154.     Use the 'rdes' template to define a “native resource” which 
  155.     starts with a routine descriptor. Such resources contain 
  156.     just PowerPC code. 
  157.     
  158.     Note that such resources can only be executed on PowerPC
  159.     machines. Executing them on a 68K machine will result 
  160.     in a crash.
  161.  
  162.     To create a “native resource”, you should first build the
  163.     executable code just as you normally do, placing the code
  164.     in a PEF container in the data fork of a file.
  165.     
  166.     You would then use something like the following:
  167.     
  168. #include "MixedMode.r"
  169.  
  170. type 'BDef' as 'rdes';
  171.  
  172. resource 'BDef' (1) {
  173.     $1,                                        // ProcInfo
  174.     $$Read("MyCode.pef")                    // Specify name of PEF file
  175. };
  176.  
  177. */
  178.  
  179. type 'rdes' { 
  180. Top:
  181.     /* Routine Descriptor */
  182.     GoMixedModeTrapType             = _MixedModeMagic;
  183.     VersionType                        = kRoutineDescriptorVersion;
  184.     fill bit [7];
  185.     SelectorsAreIndexableType        = FALSE;
  186.     Reserved1Type;
  187.     Reserved2Type;
  188.     SelectorInfoType                = 0;
  189.     RoutineCountType                = 0;
  190.  
  191.     /* Routine Record */
  192.     ProcInfoType;
  193.     Reserved3Type;
  194.     ISAType                            = kPowerPCISA;
  195.     fill bit [11];
  196.     RoutineIsDispatchedDefaultType     = FALSE;
  197.     DontPassSelectorType            = FALSE;
  198.     UseNativeISAType                = TRUE;
  199.     FragmentNeedsPreparingType        = TRUE;
  200.     ProcDescriptorIsRelativeType    = TRUE;
  201.     ProcDescriptorType                = (BeginningOfPowerPCCode-Top) / 8;
  202.     Reserved4Type;
  203.     SelectorType                    = 0;
  204.     Align LONG;
  205.  
  206. BeginningOfPowerPCCode:
  207.     hex string;                        // The PEF container starts here
  208. };
  209.  
  210.  
  211. /*
  212.     Use the 'fdes' template to define a “fat resource” which 
  213.     starts with a routine descriptor and contains both 68K and 
  214.     PowerPC code. 
  215.     
  216.     Note that such resources can only be executed on a machine
  217.     with MixedMode installed. To create “safe fat resources”
  218.     which will run on all machines, use the 'sdes' template
  219.     defined below.
  220.  
  221.     To create a “fat resource”, you should first build the
  222.     executable code just as you normally do, placing the PowerPC
  223.     code in a PEF container in the data fork of a file. The 68k
  224.     executable would be built as a stand-alone code resource, as
  225.     has historically been done.
  226.     
  227.     You would then use something like the following:
  228.     
  229. #include "MixedMode.r"
  230.  
  231. type 'BDef' as 'fdes';
  232.  
  233. resource 'BDef' (1) {
  234.     $1,                                            // 68K ProcInfo
  235.     $1,                                            // PowerPC ProcInfo
  236.     $$Resource("My68KCode.rsrc", 'oCod', 128),    // Specify file name, type and ID of resource
  237.                                                 //   containing 68k code
  238.     $$Read("MyPPCCode.pef")                        // Specify file containing PPC code in PEF format
  239. };
  240.  
  241. */
  242.  
  243. /*  Fat Routines  */
  244. type 'fdes' { 
  245. Top:
  246.     /* Routine Descriptor */
  247.     GoMixedModeTrapType             = _MixedModeMagic;
  248.     VersionType                        = kRoutineDescriptorVersion;
  249.     fill bit [7];
  250.     SelectorsAreIndexableType        = FALSE;
  251.     Reserved1Type;
  252.     Reserved2Type;
  253.     SelectorInfoType                = 0;
  254.     RoutineCountType                = 1;
  255.  
  256.     /* 68k Routine Record */
  257.     ProcInfoType;
  258.     Reserved3Type;
  259.     ISAType                            = kM68kISA;
  260.     fill bit [11];
  261.     RoutineIsDispatchedDefaultType     = FALSE;
  262.     DontPassSelectorType            = FALSE;
  263.     UseNativeISAType                = TRUE;
  264.     FragmentNeedsPreparingType        = FALSE;
  265.     ProcDescriptorIsRelativeType    = TRUE;
  266.     ProcDescriptorType                = (BeginningOf68KCode-Top) / 8;
  267.     Reserved4Type;
  268.     SelectorType                    = 0;
  269.  
  270.     /* PowerPC Routine Record 1 */
  271.     ProcInfoType;
  272.     Reserved3Type;
  273.     ISAType                            = kPowerPCISA;
  274.     fill bit [11];
  275.     RoutineIsDispatchedDefaultType     = FALSE;
  276.     DontPassSelectorType            = FALSE;
  277.     UseNativeISAType                = TRUE;
  278.     FragmentNeedsPreparingType        = TRUE;
  279.     ProcDescriptorIsRelativeType    = TRUE;
  280.     ProcDescriptorType                = (BeginningOfPowerPCCode-Top) / 8;
  281.     Reserved4Type;
  282.     SelectorType                    = 0;
  283.     Align LONG;
  284.  
  285. BeginningOf68kCode:
  286.     hex string;                // The code starts here
  287.     
  288.     Align LONG;
  289.  
  290. BeginningOfPowerPCCode:
  291.     hex string;                // The PEF container starts here
  292. };
  293.  
  294.  
  295. /*
  296.     Use the 'sdes' template to define a “safe fat resource” which 
  297.     contains both 68K and PowerPC code. A safe fat resource starts
  298.     with 68K code which is executed the first time the resource
  299.     is called. This code determines if MixedMode is present. If
  300.     so, a routine descriptor is moved to the beginning of the
  301.     resource. If not, a branch instruction to the 68K portion
  302.     of the code is placed at the beginning of the resource. 
  303.     Therefore, the first time the resource is executed, there 
  304.     is some overhead incurred. However, subsequent calls 
  305.     will be fast.
  306.     
  307.     Note: This template cannot currently be used for resources
  308.     containing code with register-based calling conventions
  309.     because the 68K code at the beginning of the resource
  310.     uses D0, A0, and A1.
  311.     
  312.     To create a “safe fat resource”, you should first build the
  313.     executable code just as you normally do, placing the PowerPC
  314.     code in a PEF container in the data fork of a file. The 68k
  315.     executable would be built as a stand-alone code resource, as
  316.     has historically been done.
  317.     
  318.     You would then use something like the following:
  319.     
  320. #include "MixedMode.r"
  321.  
  322. type 'BDef' as 'sdes';
  323.  
  324. resource 'BDef' (1) {
  325.     $1,                                            // 68K ProcInfo
  326.     $1,                                            // PowerPC ProcInfo
  327.     $$Resource("My68KCode.rsrc", 'oCod', 128),    // Specify file name, type and ID of resource
  328.                                                 //   containing 68k code
  329.     $$Read("MyPPCCode.pef")                        // Specify file containing PPC code in PEF format
  330. };
  331.  
  332. */
  333.  
  334. /*  Safe Fat Resources  */
  335. type 'sdes' { 
  336. Top:
  337.     hex string    = 
  338.         $"4E56 FFF0"      // SafeFatRsrc    LINK        A6, #-sysEnv1Size        ; Allocate a sysEnvRec
  339.         $"41EE FFF0"      //                LEA            -sysEnv1Size(A6), A0
  340.         $"7001"           //                MOVEQ        #1, D0                    ; On 6.X, Gestalt not be implemented...
  341.         $"A090"           //                _SysEnvirons    
  342.         $"4A40"           //                TST.W        D0
  343.         $"6640"           //                BNE.S        Install68K_60            ; if call fails, load up the 68K without FlushCache
  344.         $"0C68 0700 0004" //                CMPI        #$0700,systemVersion(A0)
  345.         $"6D38"           //                BLT.S        Install68K_60            ; if pre- 7.0, assume no cache        
  346.         $"303C A89F"      //                MOVE.W        #$A89F, D0                ; We have larger trap tables.  Is MixedMode installed?
  347.         $"A746"           //                _GetToolBoxTrapAddress                ; Leave _Unimplemented on the top of the stack...
  348.         $"2F08"           //                MOVE.L        A0, -(SP)                ; Unlk will clean this up
  349.         $"303C AAFE"      //                MOVE.W        #$AAFE, D0 
  350.         $"A746"           //                _GetToolBoxTrapAddress
  351.         $"B1D7"           //                CMPA.L        (SP), A0                
  352.         $"663E"           //                BNE.S        InstallPPCCode
  353.         $"41FA FFD4"      // Install68K_70    LEA            SafeFatRsrc, A0
  354.         $"30FC 6000"      //                MOVE.W        #$6000, (A0)+            ; Generate a BRA instruction
  355.         $"43FA 0044"      //                LEA            FatRD, A1
  356.         $"2029 0014"      //                MOVE.L        20(A1), D0                ; Get 68K code offset
  357.         $"5580"           //                SUBQ.L        #2, D0
  358.         $"3080"           //                MOVE.W        D0, (A0)                ; Fill in the second word of the BRA
  359.         $"303C A198"      //                MOVE.W        #$A198, D0                 ; Is _HWPriv implemented?
  360.         $"A346"           //                _GetOSTrapAddress
  361.         $"B1D7"           //                CMPA.L        (SP), A0
  362.         $"4E5E"           //                UNLK        A6
  363.         $"67B6"           //                BEQ.S        SafeFatRsrc
  364.         $"7001 A198"      //                _FlushInstructionCache
  365.         $"60B0"           //                BRA.S        SafeFatRsrc
  366.         $"4E5E"           // Install68K_60    UNLK        A6                        ; Old machine, FlushCache not supported
  367.         $"41FA FFAC"      //                LEA            SafeFatRsrc, A0                        
  368.         $"30FC 6000"      //                MOVE.W        #$6000, (A0)+            ; Generate a BRA instruction
  369.         $"43FA 001C"      //                LEA            FatRD, A1
  370.         $"2029 0014"      //                MOVE.L        20(A1), D0                ; Get 68K code offset
  371.         $"5580"           //                SUBQ.L        #2, D0
  372.         $"3080"           //                MOVE.W        D0, (A0)                ; Fill in the second word of the BRA
  373.         $"6098"           //                BRA.S        SafeFatRsrc
  374.         $"4E5E"           // InstallPPCCode    UNLK        A6
  375.         $"43FA FF94"      //                LEA            SafeFatRsrc, A1
  376.         $"41FA 0008"      //                LEA            FatRD, A0
  377.         $"7034"           //                MOVE.L        #52, D0
  378.         $"A02E"           //                _BlockMove                            ; Move R.D. to top of rsrc
  379.         $"6088";          //                BRA.S        SafeFatRsrc
  380.                           // FatRD    
  381.  
  382.     /* Routine Descriptor */
  383.     GoMixedModeTrapType             = _MixedModeMagic;
  384.     VersionType                        = kRoutineDescriptorVersion;
  385.     fill bit [7];
  386.     SelectorsAreIndexableType        = FALSE;
  387.     Reserved1Type;
  388.     Reserved2Type;
  389.     SelectorInfoType                = 0;
  390.     RoutineCountType                = 1;
  391.  
  392.     /* Routine Record */
  393.     ProcInfoType;
  394.     Reserved3Type;
  395.     ISAType                            = kM68kISA;
  396.     fill bit [11];
  397.     RoutineIsDispatchedDefaultType     = FALSE;
  398.     DontPassSelectorType            = FALSE;
  399.     UseNativeISAType                = TRUE;
  400.     FragmentNeedsPreparingType        = FALSE;
  401.     ProcDescriptorIsRelativeType    = TRUE;
  402.     ProcDescriptorType                = (BeginningOf68KCode-Top) / 8;
  403.     Reserved4Type;
  404.     SelectorType                    = 0;
  405.  
  406.     /* PowerPC Routine Record 1 */
  407.     ProcInfoType;
  408.     Reserved3Type;
  409.     ISAType    = kPowerPCISA;
  410.     fill bit [11];
  411.     RoutineIsDispatchedDefaultType     = FALSE;
  412.     DontPassSelectorType             = FALSE;
  413.     UseNativeISAType                 = TRUE;
  414.     FragmentNeedsPreparingType        = TRUE;
  415.     ProcDescriptorIsRelativeType    = TRUE;
  416.     ProcDescriptorType                 = (BeginningOfPowerPCCode-Top) / 8;
  417.     Reserved4Type;
  418.     SelectorType                     = 0;
  419.     Align LONG;
  420.  
  421. BeginningOf68KCode:
  422.     hex string;        // The 68k code starts here
  423.  
  424.     Align LONG;
  425.  
  426. BeginningOfPowerPCCode:
  427.     hex string;        // The PEF container starts here
  428. };
  429.  
  430. #endif /* __MIXEDMODE_R__ */
  431.  
  432.